package com.atguigu.gulimall.ware.service.impl;

import com.atguigu.common.constant.WareConstant;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.ware.entity.PurchaseDetailEntity;
import com.atguigu.gulimall.ware.entity.WareInfoEntity;
import com.atguigu.gulimall.ware.entity.WareSkuEntity;
import com.atguigu.gulimall.ware.feign.ProductFeignService;
import com.atguigu.gulimall.ware.service.PurchaseDetailService;
import com.atguigu.gulimall.ware.service.WareInfoService;
import com.atguigu.gulimall.ware.service.WareSkuService;
import com.atguigu.gulimall.ware.vo.MergeVO;
import com.atguigu.gulimall.ware.vo.PurchaseDoneVO;
import com.atguigu.gulimall.ware.vo.PurchaseItemsDoneVO;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.ware.dao.PurchaseDao;
import com.atguigu.gulimall.ware.entity.PurchaseEntity;
import com.atguigu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareInfoService wareInfoService;

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and( w->{
                w.eq("assignee_id",key).or().like("assignee_name",key);
            });

        }
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(status)) {
            wrapper.eq("status",status);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );
        List<PurchaseEntity> records = page.getRecords();
        records = records.stream().map( item ->{
            WareInfoEntity wareInfoEntity = wareInfoService.getById(item.getWareId());
            if (!ObjectUtils.isEmpty(wareInfoEntity)){
                item.setWareName(wareInfoEntity.getName());
            }
            return item;
        }).collect(Collectors.toList());

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceive(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status",0).or().eq("status",1)
        );
        return new PageUtils(page);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R mergePurchase(MergeVO mergeVO){
        Long purchaseId = mergeVO.getPurchaseId();
        //新建的采购单
        if (ObjectUtils.isEmpty(purchaseId)) {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setPriority(1);
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        //获取所有的需求单id
        List<Long> items = mergeVO.getItems();
        //创建几个参数
        Long wareId = null;
        BigDecimal price = BigDecimal.ZERO;
        //这里是判断当需求单现在的状态
        List<PurchaseDetailEntity> purchaseDetailEntityStream = new ArrayList<>();
        Long temp = null;
        for (int i = 0; i < items.size(); i++) {
            PurchaseDetailEntity resp = purchaseDetailService.getById(items.get(i));
            if (i == 0) {
                temp = resp.getWareId();
            } else {
                Long id = resp.getWareId();
                if (!id.equals(temp)) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.error(HttpStatus.SC_NOT_ACCEPTABLE,"请选择需求相同的两个仓库进行合并！");
                }

            }
            //只需当前状态为创建的
            if (resp.getStatus() == WareConstant.PurchaseDetailStatusEnum.CREATED.getCode()) {
                wareId = resp.getWareId();
                price = price.add(resp.getSkuPrice());
                purchaseDetailEntityStream.add(resp);
            }
        }
        //如果没满足全部返回
        if (items.size() > purchaseDetailEntityStream.size()){
            //手动进行事务的回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error(HttpStatus.SC_NOT_ACCEPTABLE,"需求单已被分配，无法继续分配！");
        }

        //获取采购的需求
        Long finalPurchaseId = purchaseId;
        //将需求id遍历成集合随后修改
        List<PurchaseDetailEntity> collect = items.stream().map(item -> {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            detailEntity.setId(item);
            detailEntity.setPurchaseId(finalPurchaseId);
            detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return detailEntity;
        }).collect(Collectors.toList());
        //修改需求的状态
        purchaseDetailService.updateBatchById(collect);
        //更新时间并且添加仓库和订单金额
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setUpdateTime(new Date());
        purchaseEntity.setWareId(wareId);
        purchaseEntity.setAmount(price);
        this.updateById(purchaseEntity);
        return R.ok();
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void receive(List<Long> ids) {
        //确认当前采购单是新建或者是已分配状态
        List<PurchaseEntity> collect = ids.stream().map(id -> {
            PurchaseEntity getById = this.getById(id);
            return getById;
        }).filter(item -> {
            //进行过滤
            if (item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getCode() ||
                    item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                return true;
            } else {
                return false;
            }
            //给状态进行赋值
        }).map(item ->{
            item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            item.setUpdateTime(new Date());
            return item;
        }).collect(Collectors.toList());
        //改变采购单的状态
        this.updateBatchById(collect);
        //改变采购需求的状态
        collect.forEach( item ->{
            //查询该采购单的需求
            List<PurchaseDetailEntity> list = purchaseDetailService.listDetailByPurchaseId(item.getId());
            if (!ObjectUtils.isEmpty(list)){
                //进行遍历然后修改状态
                list = list.stream().map( entity ->{
                    entity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
                    return entity;
                }).collect(Collectors.toList());
                //执行修改
                purchaseDetailService.updateBatchById(list);
            }
        });
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void done(PurchaseDoneVO doneVO) {
        //采购单的id
        Long id = doneVO.getId();
        //改变采购需求的状态
        Boolean flag = true;
        List<PurchaseItemsDoneVO> items = doneVO.getItems();
        List<PurchaseDetailEntity> updates = new ArrayList<>();
        //这里是修改需求单的状态
        if (!ObjectUtils.isEmpty(items)) {
            for (PurchaseItemsDoneVO item : items) {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                if (item.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROE.getCode()) {
                    flag = false;
                }
                detailEntity.setStatus(item.getStatus());
                detailEntity.setId(item.getItemId());
                updates.add(detailEntity);
            }
            purchaseDetailService.updateBatchById(updates);
        }
        //改变采购单的状态
        PurchaseEntity entity = new PurchaseEntity();
        entity.setId(id);
        entity.setStatus(flag?WareConstant.PurchaseStatusEnum.FINSH.getCode() : WareConstant.PurchaseStatusEnum.HASERROE.getCode());
        entity.setUpdateTime(new Date());
        this.updateById(entity);
        //将成功的采购进行入库
        items.forEach( item ->{
            Integer status = item.getStatus();
            if (status.equals(WareConstant.PurchaseDetailStatusEnum.FINSH.getCode())) {
                //根据需求单查询详细信息
                Long itemId = item.getItemId();
                PurchaseDetailEntity detailEntity = purchaseDetailService.getById(itemId);
                //创建一个仓库入参对象
                WareSkuEntity skuEntity = new WareSkuEntity();
                skuEntity.setSkuId(detailEntity.getSkuId());
                skuEntity.setWareId(detailEntity.getWareId());
                skuEntity.setStock(detailEntity.getSkuNum());
                skuEntity.setStockLocked(0);
                try {
                    R info = productFeignService.getSkuBySkuId(detailEntity.getSkuId());
                    Map<String,Object> data = (Map<String,Object>)info.get("skuInfo");
                    if (info.getCode() == 0){
                        skuEntity.setSkuName((String) data.get("skuName"));
                    }
                    System.out.println("data: " + data);
                }catch (Exception e) {
                }
                wareSkuService.addStock(skuEntity);
            }
        });
    }

    //TODO 采购失败要添加原因，如果本来要采购10个，只采购8个。添加实采数量
}